package it.polito.connectedcar.message;

import it.polito.connectedcar.tcc.zone.Token;
import it.polito.connectedcar.vehicle.VehicleNeighborhood;
import it.polito.connectedcar.vehicle.VehicleZone;

import java.net.InetSocketAddress;
import java.util.concurrent.BlockingQueue;

/**
 * a MessageProcessor is an intermediate actor which extracts messages from a
 * Queue ( filled by the network layer ) , validates each message and invoke all
 * the registered listeners to inform them about the availability of a new
 * message. The TCCMessageProcessor deals just with messages coming from the
 * TCC. Is in charge of checking whether a message coming from a TCC is a valid
 * one, by looking at the token and source address of the message and comparing
 * against the ones the vehicle already contains. If those information are not
 * present , the message is dropped, otherwise it is passed to the regeistered
 * listeners.
 * 
 * 
 * @author Nicola Aresta
 * 
 */
public class TCCMessageProcessor extends Thread {

	private TCCMessageListener tccMessageListener;
	private VehicleNeighborhood vehicleNeighborhood;
	private BlockingQueue<VehicleFromTCCMessage> tccMessageQueue;

	private volatile boolean canRun;

	public TCCMessageProcessor(VehicleNeighborhood vehicleNeighborhood,
			MessageQueueFactory messageQueueFactory) {
		tccMessageQueue = messageQueueFactory.getTCCMessageQueue();
		this.vehicleNeighborhood = vehicleNeighborhood;
		canRun = true;
	}

	@Override
	public void run() {
		while (canRun) {
			try {
				VehicleFromTCCMessage m = tccMessageQueue.take();
				InetSocketAddress is = m.getSourceAddress();
				Token t = null;
				for (VehicleZone zone : vehicleNeighborhood.getNeighbors()) {
					if (zone.getTccAddress().equals(is)) {
						t = zone.getZoneToken();
						break;
					}
				}

				try {
					if (t != null && m.processMessage(t)&& tccMessageListener != null)
						tccMessageListener.onMessageReceived(m);

				} catch (Exception e) {
					e.printStackTrace();
				}
				/*
				 * using the token t , recalculate the digest on the message
				 * payload:
				 */

				/*
				 * 1) verify authenticity and integrity 2) extract all records
				 * and verify authorization of all records 3) apply intelligence
				 * on data 4) operates on Vehicle info
				 */

			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		}
	}

	public void askStop() {
		this.canRun = false;
	}

	public TCCMessageListener getTccMessageListener() {
		return tccMessageListener;
	}

	public void setTccMessageListener(TCCMessageListener tccMessageListener) {
		this.tccMessageListener = tccMessageListener;
	}

}
